package com.example.ymm.modules1.service.impl.user;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
import com.example.ymm.base.BaseServiceImpl;
import com.example.ymm.exception.YmException;
import com.example.ymm.model.TableList;
import com.example.ymm.model.YmPageDto;
import com.example.ymm.modules1.entity.ms.DEmployee;
import com.example.ymm.modules1.entity.my.user.*;
import com.example.ymm.modules1.mapper.my.user.OfficeUserMapper;
import com.example.ymm.modules1.query.OfficeUserQueryCriteria;
import com.example.ymm.modules1.service.dd.DdUserServer;
import com.example.ymm.modules1.service.dto.ImportOfficeUserDto;
import com.example.ymm.modules1.service.dto.OfficeQualifiedDto;
import com.example.ymm.modules1.service.dto.OfficeQualifiedItemDto;
import com.example.ymm.modules1.service.dto.ViewDeptOfficeUser;
import com.example.ymm.modules1.service.ms.DEmployeeService;
import com.example.ymm.modules1.service.user.*;
import com.example.ymm.util.*;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.*;

@Service
//@Transactional
//@DS("slave2")

@Slf4j
public class OfficeUserServiceImpl extends BaseServiceImpl<OfficeUserMapper, OfficeUser> implements OfficeUserService {

    @Autowired
    DbUserService dbUserService;
    @Autowired
    DEmployeeService dEmployeeService;

    @Autowired
    DdUserServer ddUserServer;

    @Autowired
    OfficePostRequestService officePostRequestService;
    @Autowired
    OfficeScoreSettingService officeScoreSettingService;
    @Autowired
    OfficeSatisfactionMainService officeSatisfactionMainService;

    @Override
    public TableList<ViewDeptOfficeUser> list(OfficeUserQueryCriteria criteria, YmPageDto pageDto) {
        getPage(pageDto);
//        PageHelper.offsetPage(ymPage.getPage(),ymPage.getPageSize());
        List<ViewDeptOfficeUser> maps = getDeptUserList(criteria);

        PageInfo<ViewDeptOfficeUser> pageInfo = new PageInfo<>(maps);
        TableList<ViewDeptOfficeUser> tableList=new TableList<>(pageInfo);
        return tableList;
    }

    public List<OfficeUser> queryAll(OfficeUserQueryCriteria criteria) {
        List<OfficeUser> result =baseMapper.selectList(QueryHelpPlus.getPredicate(OfficeUser.class, criteria));
        return result;
    }


    @Override
    public OfficeUser findByUserName(String userName) {
        OfficeUserQueryCriteria criteria=new OfficeUserQueryCriteria();
        criteria.setUserName(userName);
        List<OfficeUser> officeUsers = queryAll(criteria);
        if(officeUsers.size()>0){
            return officeUsers.get(0);
        }
        return null;
    }

    @Override
    public OfficeUser findByUserId(String userId) {
        OfficeUserQueryCriteria criteria=new OfficeUserQueryCriteria();
        criteria.setUserId(userId);
        List<OfficeUser> officeUsers = queryAll(criteria);
        if(officeUsers.size()>0){
            return officeUsers.get(0);
        }
        return null;
    }

    @Override
    public List<String> importOfficeUser(ImportOfficeUserDto dto) {
        List<String> errors=new ArrayList<>();
        List<OfficeUser> list = dto.getList();
        List<OfficeUser> addUsers = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            OfficeUser officeUser=list.get(i);
            if(UtilValidate.isEmpty(officeUser.getUserName())){
                errors.add("第"+(i+1)+"行 姓名不能为空!");
                continue;
            }
            String userName = officeUser.getUserName().trim();
            officeUser.setUserName(userName);

            if(UtilValidate.isNotEmpty(officeUser.getEducation())){
                officeUser.setEducation(officeUser.getEducation().trim());
            }
            if(UtilValidate.isNotEmpty(officeUser.getSpecialty())){
                officeUser.setSpecialty(officeUser.getSpecialty().trim());
            }

            if(UtilValidate.isNotEmpty(officeUser.getAddTimeStr())){
                String date_str=officeUser.getAddTimeStr().trim()+" 00:00:00";
                Date date = DateKit.dateFormat(date_str);
                officeUser.setAddTime(new Timestamp(date.getTime()));
            }

            OfficeUser byUserName = findByUserName(userName);
            if(UtilValidate.isNotEmpty(byUserName)){

            }else{
                //新增
                addUsers.add(officeUser);
            }

        }
        if(addUsers.size()>0){
            for (OfficeUser officeUser : addUsers) {
                DbUser dbUser = dbUserService.findByUserName(officeUser.getUserName());
                if(UtilValidate.isNotEmpty(dbUser)){
                    officeUser.setUserName(dbUser.getUserName());
                    officeUser.setUserId(dbUser.getUserId());
                }
            }
            // 动态切换数据源
            DynamicDataSourceContextHolder.clear();
            DynamicDataSourceContextHolder.push("slave");
            for (OfficeUser officeUser : addUsers) {
                //查询生日
                DEmployee userInfo = dEmployeeService.getUserInfo(officeUser.getUserName());
                if(UtilValidate.isNotEmpty(userInfo)){
                    officeUser.setBirthdate(userInfo.getBirthdate());
                }
            }
            // 使用后清理，继续使用默认数据源
            DynamicDataSourceContextHolder.clear();
            DynamicDataSourceContextHolder.push("master");

            saveOrUpdateBatch(addUsers);
        }


        return errors;
    }


    @Override
    public void syncOfficeUser() {
        OfficeUserQueryCriteria criteria = new OfficeUserQueryCriteria();
//        criteria.setKeyword("陈俊珍");
        List<OfficeUser> officeUsers = queryAll(criteria);
        for (OfficeUser officeUser : officeUsers) {
            if(UtilValidate.isNotEmpty(officeUser.getUserId())){
                JSONObject jsonObject = ddUserServer.getUserInfoByUserId(officeUser.getUserId());
                if(UtilValidate.isNotEmpty(jsonObject)){
//                String roleName = jsonObject.getJSONObject("role_list").getString("name");
//                officeUser.setRoleName(roleName);
                    officeUser.setDdText(jsonObject.toJSONString());

                    String roleName = jsonObject.getString("title");
                    officeUser.setRoleName(roleName);
                    //获取一级和二级部门id
                    List<String> deptIds=new ArrayList<>();

                    JSONArray dept_list_arr = jsonObject.getJSONArray("dept_order_list");
                    for (int i = 0; i < dept_list_arr.size(); i++) {
                        String dept_id = dept_list_arr.getJSONObject(i).getString("dept_id");
                        deptIds.add(dept_id);
                    }
                    if(UtilValidate.isNotEmpty(deptIds)){
                        officeUser.setDeptIdList(String.join(",", deptIds));
                        officeUser.setDeptId(deptIds.get(0));
                    }
                    saveOrUpdate(officeUser);
                }

            }
        }

        //自动匹配岗位
        similarityMatching();

    }

    @Override
    public List<ViewDeptOfficeUser> getDeptUserList(OfficeUserQueryCriteria criteria) {
        List<ViewDeptOfficeUser> deptUserList = baseMapper.getDeptUserList(criteria);
        Date now = new Date();
        for (ViewDeptOfficeUser officeUser : deptUserList) {
            /**
             * 计算年龄
             */
            if(UtilValidate.isNotEmpty(officeUser.getBirthdate())){
                int yearNum = DateKit.dateDiff(4, officeUser.getBirthdate(), now);
                officeUser.setYearNum(yearNum);
            }
            /**
             * 司龄
             */
            int workNum = DateKit.dateDiff(4, officeUser.getAddTime(), now);
            officeUser.setWorkNum(workNum);

            /**
             * 工龄
             */
            if(UtilValidate.isNotEmpty(officeUser.getFirstWordTime())){
                int firstWordNum = DateKit.dateDiff(4, officeUser.getFirstWordTime(), now);
                officeUser.setFirstWordNum(firstWordNum);
            }
            /**
             * 管理经验
             */
            if(UtilValidate.isNotEmpty(officeUser.getManageYear())){
                if(UtilValidate.isNotEmpty(officeUser.getFirstManageTime())){
                    int firstManageNum = DateKit.dateDiff(4, officeUser.getFirstManageTime(), now);
                    officeUser.setFirstManageNum(firstManageNum+officeUser.getManageYear());
                }else{
                    officeUser.setFirstManageNum(officeUser.getManageYear());
                }
            }

            /**
             * 专业经验
             */
            if(UtilValidate.isNotEmpty(officeUser.getSpecialtyYear())){
                if(UtilValidate.isNotEmpty(officeUser.getFirstPostTime())){
                    int firstPostNum = DateKit.dateDiff(4, officeUser.getFirstPostTime(), now);
                    officeUser.setFirstPostNum(firstPostNum+officeUser.getManageYear());
                }else{
                    officeUser.setFirstPostNum(officeUser.getSpecialtyYear());
                }
            }


        }
        return deptUserList;
    }


    @Override
    public void similarityMatching() {
        List<OfficePostRequest> officePostRequests = officePostRequestService.queryAll(null);
        List<ViewDeptOfficeUser> deptUserList = getDeptUserList(null);
        for (ViewDeptOfficeUser deptUser : deptUserList) {
            String postRequestId=null;
            if(UtilValidate.isNotEmpty(deptUser.getRoleName())){
                //匹配相似度
                for(OfficePostRequest post: officePostRequests){
                    if(post.getRoleName().equals(deptUser.getRoleName())){
                        postRequestId=post.getPostRequestId();
                    }else if(post.getRoleName().contains(deptUser.getRoleName())){
                        postRequestId=post.getPostRequestId();
                    }else if(deptUser.getRoleName().contains(post.getRoleName())){
                        postRequestId=post.getPostRequestId();
                    }
                }
            }
            if(UtilValidate.isNotEmpty(postRequestId)){
                deptUser.setPostRequestId(postRequestId);
                saveOrUpdate(deptUser);
            }

        }
    }


    @Override
    public List<OfficeQualifiedDto> qualifiedList(OfficeUserQueryCriteria criteria) {
        criteria.setPostRequestIdIsNotNull("1");
        List<ViewDeptOfficeUser> deptUserList = getDeptUserList(criteria);
        List<OfficePostRequest> posts = officePostRequestService.queryAll(null);
        List<OfficeScoreSetting> settings = officeScoreSettingService.queryAll(null);

        //学历map
        Map<String, Integer> educationMap = getEducationMap();

        List<OfficeQualifiedDto> list = new ArrayList<>(deptUserList.size());
        for (ViewDeptOfficeUser deptUser : deptUserList) {
            OfficeQualifiedDto officeQualifiedDto = new OfficeQualifiedDto();
            officeQualifiedDto.setUserName(deptUser.getUserName());
            officeQualifiedDto.setUserId(deptUser.getUserId());
            officeQualifiedDto.setPostRoleName(deptUser.getPostRoleName());
            OfficePostRequest postRequest=null;
            OfficeScoreSetting scoreSetting=null;
            //匹配岗位
            for(OfficePostRequest post: posts){
                if(post.getPostRequestId().equals(deptUser.getPostRequestId())){
                    postRequest=post;
                }
            }
            //查询人员类型的最大配置
            for(OfficeScoreSetting setting: settings){
                if(setting.getType().equals(deptUser.getType())){
                    scoreSetting=setting;
                }
            }
            if(UtilValidate.isEmpty(postRequest)){
                throw new YmException(deptUser.getUserName()+"匹配不到岗位要求");
            }

            //处理评价数据
            List<OfficeQualifiedItemDto> items=new ArrayList<>();

            /**
             * 学历
             */
            OfficeQualifiedItemDto d1 = new OfficeQualifiedItemDto();//学历
            //获取用户学历等级
            Integer user_education = educationMap.get(deptUser.getEducation());
            if(UtilValidate.isEmpty(user_education)){
                user_education=1;//最低要求
            }
            //获取岗位要求学历等级
            Integer request_education = educationMap.get(postRequest.getEducation());
            d1.setGroupName("学历");
            d1.setEvaluationStandard(postRequest.getEducation());//评价标准
            d1.setUserInfo(deptUser.getEducation());//个人信息

            //获得评分系数
            BigDecimal rate=null;

            if(user_education >request_education){
                rate=new BigDecimal("1.2");//高出无论多少级别都按 120%
            }else if(request_education.equals(user_education)){
                rate=BigDecimal.ONE;//完全匹配 按 100%
            }else {
                //计算低出的级别
                Integer df=request_education-user_education;
                if(df.equals(1)){
                    rate=new BigDecimal("0.6");//低于1级别
                }else{
                     //超出1级别
                    rate=BigDecimal.ZERO;
                }
            }
            if(UtilValidate.isEmpty(rate)){
                throw new YmException("蓄力评分系数不能为空！");
            }
            //计算学历分数
            BigDecimal education_score = new BigDecimal(scoreSetting.getEducation()).multiply(rate).setScale(2, BigDecimal.ROUND_HALF_UP);
            d1.setEvaluationScore(scoreSetting.getEducation());
            d1.setResultScore(education_score);
            d1.setRate(rate);
            items.add(d1);

            /**
             * 工作经验
             */
            OfficeQualifiedItemDto d2 = new OfficeQualifiedItemDto();//工作经验
            d2.setGroupName("工作经验");
            d2.setEvaluationStandard(getIntString(postRequest.getWorkNum()));//评价标准
            d2.setUserInfo(getIntString(deptUser.getWorkNum()));//个人信息
            //获得评分系数-工作经验
            BigDecimal rate2=null;
            Integer request_level = getOtherYearLevel(postRequest.getWorkNum());
            Integer user_level = 1;
            if(UtilValidate.isNotEmpty(deptUser.getWorkNum())){
                user_level = getOtherYearLevel(deptUser.getWorkNum());
            }

            if(user_level>request_level){
                rate2=new BigDecimal("1.2");//高出无论多少级别都按 120%
            }else if(request_level.equals(user_level)){
                rate2=BigDecimal.ONE;//完全匹配 按 100%
            }else {
                //计算低出的级别
                Integer df=request_level-user_level;
                if(df.equals(1)){
                    rate2=new BigDecimal("0.6");//低于1级别
                }else{
                    //超出1级别
                    rate2=BigDecimal.ZERO;
                }
            }

            //计算 工作年限 分数
            BigDecimal work_score = new BigDecimal(scoreSetting.getWorkNum()).multiply(rate2).setScale(2, BigDecimal.ROUND_HALF_UP);
            d2.setEvaluationScore(scoreSetting.getWorkNum());
            d2.setResultScore(work_score);
            d2.setRate(rate2);
            items.add(d2);

            /**
             * 管理经验
             */
            OfficeQualifiedItemDto d3 = new OfficeQualifiedItemDto();//管理经验
            d3.setGroupName("管理经验");
            d3.setEvaluationStandard(getIntString(postRequest.getManageNum()));//评价标准
            d3.setUserInfo(getIntString(deptUser.getManageYear()));//个人信息
            BigDecimal rate3=null;
            Integer request_manage = getOtherYearLevel(UtilValidate.isNotEmpty(postRequest.getManageNum())?postRequest.getManageNum():0);
            Integer user_manage = getOtherYearLevel(UtilValidate.isNotEmpty(deptUser.getManageYear())?deptUser.getManageYear():0);


            if(user_manage >request_manage){
                rate3=new BigDecimal("1.2");//高出无论多少级别都按 120%
            }else if(request_manage.equals(user_manage)){
                rate3=BigDecimal.ONE;//完全匹配 按 100%
            }else {
                //计算低出的级别
                Integer df=request_manage-user_manage;
                if(df.equals(1)){
                    rate3=new BigDecimal("0.6");//低于1级别
                }else{
                    //超出1级别
                    rate3=BigDecimal.ZERO;
                }
            }

            //计算 管理经验 分数
            BigDecimal manage_score = new BigDecimal(UtilValidate.isNotEmpty(scoreSetting.getManageNum())?scoreSetting.getManageNum():0).multiply(rate3).setScale(2, BigDecimal.ROUND_HALF_UP);
            d3.setEvaluationScore(scoreSetting.getManageNum());
            d3.setResultScore(manage_score);
            d3.setRate(rate3);
            items.add(d3);

            /**
             * 专业经验
             */
            OfficeQualifiedItemDto d4 = new OfficeQualifiedItemDto();//专业经验
            d4.setGroupName("专业经验");
            d4.setEvaluationStandard(getIntString(postRequest.getSpecialtyNum()));//评价标准
            d4.setUserInfo(getIntString(deptUser.getSpecialtyYear()));//个人信息
            BigDecimal rate4=null;
            Integer request_specialty = getOtherYearLevel(UtilValidate.isNotEmpty(postRequest.getSpecialtyNum())?postRequest.getSpecialtyNum():0);
            Integer user_specialty = getOtherYearLevel(UtilValidate.isNotEmpty(deptUser.getSpecialtyYear())?deptUser.getSpecialtyYear():0);


            if(user_specialty >request_specialty){
                rate4=new BigDecimal("1.2");//高出无论多少级别都按 120%
            }else if(request_specialty.equals(user_specialty)){
                rate4=BigDecimal.ONE;//完全匹配 按 100%
            }else {
                //计算低出的级别
                Integer df=request_specialty-user_specialty;
                if(df.equals(1)){
                    rate4=new BigDecimal("0.6");//低于1级别
                }else{
                    //超出1级别
                    rate4=BigDecimal.ZERO;
                }
            }

            //计算 管理经验 分数
            BigDecimal specialty_score = new BigDecimal(UtilValidate.isNotEmpty(scoreSetting.getSpecialtyNum())?scoreSetting.getSpecialtyNum():0).multiply(rate4).setScale(2, BigDecimal.ROUND_HALF_UP);
            d4.setEvaluationScore(UtilValidate.isNotEmpty(scoreSetting.getSpecialtyNum())?scoreSetting.getSpecialtyNum():0);
            d4.setResultScore(specialty_score);
            d4.setRate(rate4);
            items.add(d4);


            /**
             * 专业相符
             */
            OfficeQualifiedItemDto d8 = new OfficeQualifiedItemDto();//专业相符
            d8.setGroupName("专业相符");
            d8.setEvaluationStandard(postRequest.getSpecialty());//评价标准
            d8.setUserInfo(deptUser.getSpecialtyMatching());//个人信息
            BigDecimal rate8=new BigDecimal("0.6");
//            Integer request_like = getOtherYearLevel(UtilValidate.isNotEmpty(postRequest.getSpecialtyNum())?postRequest.getSpecialtyNum():0);
//            Integer user_like = getOtherYearLevel(UtilValidate.isNotEmpty(deptUser.getSpecialtyYear())?deptUser.getSpecialtyYear():0);

            String specialtyMatching = deptUser.getSpecialtyMatching();
            if(UtilValidate.isNotEmpty(specialtyMatching)){
                if("相近".equals(specialtyMatching)){
                    rate8=BigDecimal.ONE;//完全匹配 按 100%

                } else if ("相符".equals(specialtyMatching)) {
                    rate8=new BigDecimal("1.2");//高出无论多少级别都按 120%

                }else{
                    //不相符
                    rate8=new BigDecimal("0.6");//低于1级别

                }
            }

            //计算 专业相符 分数
            BigDecimal specialty_like_score = new BigDecimal(UtilValidate.isNotEmpty(scoreSetting.getSpecialtyMatching())?scoreSetting.getSpecialtyMatching():0).multiply(rate8).setScale(2, BigDecimal.ROUND_HALF_UP);
            d8.setEvaluationScore(UtilValidate.isNotEmpty(scoreSetting.getSpecialtyMatching())?scoreSetting.getSpecialtyMatching():0);
            d8.setResultScore(specialty_like_score);
            d8.setRate(rate8);
            items.add(d8);

            /**
             * 历史业绩
             */
            OfficeSatisfactionMain satisfactionMain = officeSatisfactionMainService.getByUserIdAndYear(deptUser.getUserId(), criteria.getYear());

            OfficeQualifiedItemDto d6 = new OfficeQualifiedItemDto();//历史业绩
            d6.setGroupName("历史业绩");
            BigDecimal rate6=BigDecimal.ZERO;
            d6.setResultScore(BigDecimal.ZERO);
            if(UtilValidate.isNotEmpty(satisfactionMain)){
                String level = satisfactionMain.getLevel();
                d6.setUserInfo(level);
                ////满意程度: 不太满意，基本满意，满意，很满意
                if("不太满意".equals(level)){
                    rate6=new BigDecimal("0.6");
                }else if("基本满意".equals(level)){
                    rate6=new BigDecimal("0.8");

                }else if("满意".equals(level)){
                    rate6=new BigDecimal("1.1");

                }else if("很满意".equals(level)){
                    rate6=new BigDecimal("1.3");

                }
                //计算 历史业绩 分数
                BigDecimal history_score = new BigDecimal(scoreSetting.getHistory()).multiply(rate6).setScale(2, BigDecimal.ROUND_HALF_UP);
                d6.setEvaluationScore(scoreSetting.getHistory());//评价分数
                d6.setResultScore(history_score);
                d6.setRate(rate6);
            }

            items.add(d6);

            /**
             * 合计
             */
            OfficeQualifiedItemDto d7 = new OfficeQualifiedItemDto();//合计
            d7.setGroupName("合计");
//            d7.setEvaluationScore(100);//评价分数
            //计算合计
            BigDecimal result_score=BigDecimal.ZERO;
            for (OfficeQualifiedItemDto dto: items){
                if(UtilValidate.isNotEmpty(dto.getResultScore())){
                    result_score=result_score.add(dto.getResultScore());
                }
            }

            d7.setResultScore(result_score);
            items.add(d7);


            //设置数据
            for (OfficeQualifiedItemDto dto: items){
                dto.setUserId(officeQualifiedDto.getUserId());
                dto.setUserName(officeQualifiedDto.getUserName());
                dto.setPostRoleName(officeQualifiedDto.getPostRoleName());
            }

            officeQualifiedDto.setList(items);
            list.add(officeQualifiedDto);
        }
        return list;
    }


    /**
     * 获取学历的级别
     * @return
     */
    public Map<String,Integer> getEducationMap(){
        Map<String,Integer> map=new LinkedHashMap<>();
        map.put("无",1);

        map.put("初中",2);
        map.put("中专",2);
        map.put("专科",2);

        map.put("高中",3);
        map.put("大专",3);
        map.put("本科",4);
        map.put("研究生",5);
        map.put("博士",6);
        return  map;
    }

    /**
     * 获取
     * 工作经验，管理经验，专业经验 的评价等级
     * @param year
     * @return
     */
    public Integer getOtherYearLevel(Integer year){
        Integer yearLevel=1;
        if(year<=1){
            yearLevel=2;
        }else if(year>1&&year<=3){
            yearLevel=3;
        }else if(year>3&&year<=5){
            yearLevel=4;
        }else if(year>5&&year<=10){
            yearLevel=5;
        }else{
            yearLevel=6;
        }
        return yearLevel;
    }

    public String getIntString(Integer value){
        String str="";
        if(value!=null){
            str=value+"";
        }
        return str;
    }

}
